﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SPMS.Log.Utility;
using SPMS.Utility;

namespace SPMS.Log.Core
{
    /// <summary>
    /// 日志输出器可连接接口默认实现
    /// </summary>
    /// <remarks></remarks>
    /// <history>
    /// [zanezeng]               2009/10/9 16:30    创建
    /// </history>
    public sealed class LogAppenderAttachableImplement : ILogAppenderAttachable
    {
        #region ---ILogAppenderAttachable

        /// <summary>
        /// 获得关联的所有日志输出器
        /// </summary>
        /// <value>关联的所有日志输出器</value>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 12:11    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/30 13:41    创建
        /// </history>
        public ILogAppender[] Appenders
        {
            get
            {
                return this.m_Appenders.Values.ToArray();
            }
        }

        /// <summary>
        /// 获得给定名称的日志输出器
        /// </summary>
        /// <param name="name">要获得的日志输出器的名称</param>
        /// <returns>给定名称的日志输出器</returns>
        /// <remarks></remarks>
        /// <exception cref="ArgumentNullException"><paramref name="name"/>为空字符串或者为<c>null</c>引用。</exception>
        /// <history>
        /// [zanezeng]               2009/9/25 12:18    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/11/24 14:54    创建
        /// </history>
        public ILogAppender GetAppender(string name)
        {
            //断言参数
            ArgumentAssert.AssertStringArgumentNotNullOrEmpty(name, "name");

            //用于保存日志追加器
            ILogAppender appender = null;

            //查询日志追加器
            this.m_Appenders.TryGetValue(name, out appender);

            //返回日志追加器
            return appender;
        }

        /// <summary>
        /// 添加日志输出器
        /// </summary>
        /// <param name="appender">要添加的日志输出器。</param>
        /// <remarks></remarks>
        /// <exception cref="ArgumentNullException"><paramref name="appender"/>为<c>null</c>引用。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="appender"/>的<see cref="ILogAppender.Name"/>为空字符串或者为<c>null</c>引用。</exception>
        /// <history>
        /// [zanezeng]               2009/9/25 12:12    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/11/24 14:54    创建
        /// </history>
        public void AddAppender(ILogAppender appender)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(appender, "appender");

            //判断日志追加器的名称
            if (string.IsNullOrEmpty(appender.Name))
            {
                //抛出异常
                throw new ArgumentException("appender");
            }

            //注册日志追加器
            this.m_Appenders[appender.Name] = appender;
        }

        /// <summary>
        /// 删除指定日志输出器
        /// </summary>
        /// <param name="appender">要删除的日志输出器</param>
        /// <returns>
        /// 	<c>true</c>：删除成功<br/>
        /// 	<c>false</c>：删除失败
        /// </returns>
        /// <exception cref="ArgumentNullException"><paramref name="appender"/>为<c>null</c>引用。</exception>
        /// <exception cref="ArgumentNullException"><paramref name="appender"/>的<see cref="ILogAppender.Name"/>为空字符串或者为<c>null</c>引用。</exception>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 12:14    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/11/24 14:55    创建
        /// </history>
        public bool RemoveAppender(ILogAppender appender)
        {
            //断言参数
            ArgumentAssert.AssertArgumentNotNull(appender, "appender");

            //判断日志追加器的名称
            if (string.IsNullOrEmpty(appender.Name))
            {
                //抛出异常
                throw new ArgumentException("appender");
            }

            //用于保存同名的日志追加器
            ILogAppender existedAppender = null;

            //检索同名的日志追加器
            if (this.m_Appenders.TryGetValue(appender.Name, out existedAppender) && object.ReferenceEquals(existedAppender, appender))
            {
                //如果是同一个日志追加器，则直接删除
                return this.m_Appenders.Remove(appender.Name);
            }

            //默认返回删除失败
            return false;
        }

        /// <summary>
        /// 删除给定名称的日志输出器
        /// </summary>
        /// <param name="name">要删除的日志输出器的名称</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"><paramref name="name"/>为空字符串或者为<c>null</c>引用。</exception>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 12:17    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2010/11/24 14:59    创建
        /// </history>
        public ILogAppender RemoveAppender(string name)
        {
            //断言参数
            ArgumentAssert.AssertStringArgumentNotNullOrEmpty(name, "name");

            //用于保存同名的日志追加器
            ILogAppender existedAppender = null;

            //检索同名的日志追加器
            if (this.m_Appenders.TryGetValue(name, out existedAppender))
            {
                //如果是同一个日志追加器，则直接删除
                this.m_Appenders.Remove(name);
            }

            //返回删除的日志追加器
            return existedAppender;
        }

        /// <summary>
        /// 清除所有的日志输出器
        /// </summary>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/25 12:17    创建
        /// </history>
        /// <remarks></remarks>
        /// <history>
        /// [zanezeng]               2009/9/30 13:42    创建
        /// </history>
        public void ClearAppenders()
        {
            //清除日志记录器
            this.m_Appenders.Clear();
        }

        #endregion

        #region ---Field

        /// <summary>
        /// 日志记录器列表
        /// </summary>
        private SynchronizedDictionary<string, ILogAppender> m_Appenders = new SynchronizedDictionary<string, ILogAppender>(StringComparer.InvariantCulture);

        #endregion
    }
}
